<!--
*@Author: QWP
*@Description: 
*@Date: 2024-07-15 10:46:21
-->
<template>
  <div
    class="f-h-100 f-flex-column"
    :class="{ 'u-tencent-editor': isLikeTencent }"
  >
    <Toolbar
      class="u-editor-tool"
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      mode="default"
    />
    <div
      style="display: block; flex: 1"
      :class="{ 'u-tencent-editor-box': isLikeTencent }"
    >
      <div class="editor-container">
        <div id="title-container" v-if="isLikeTencent">
          <input
            v-model="title"
            placeholder="请输入标题..."
            @change="inputChange"
          />
        </div>
        <Editor
          class="u-editor"
          v-model="valueHtml"
          :defaultConfig="editorConfig"
          mode="default"
          @onCreated="handleCreated"
          @onChange="handlerChange"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
defineOptions({
  name: 'u-wang-editor',
});
import {
  onBeforeUnmount,
  ref,
  reactive,
  computed,
  onMounted,
  shallowRef,
  useAttrs,
  watch,
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import {
  IToolbarConfig,
  IEditorConfig,
  DomEditor,
  Boot,
} from '@wangeditor/editor';
import { imgApi } from '@/http/api';
import * as fileApi from '@/service/file';
import { CustomBtn } from './customBtn.ts';
import { nullC } from '@/util/common.js';
import { formatImgUrl } from '@/util/format.ts';

interface _IFileParams {
  bucket: string;
  biztype: string;
}

interface Props {
  value?: string;
  title?: string;
  valueType?: string; // 返回值类型，html, text
  editConfig?: IEditorConfig; // 编辑器配置
  fileParams?: _IFileParams; // 附件参数
  isLikeTencent?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
  valueType: 'html',
  isLikeTencent: false,
});
const emits = defineEmits(['update:value', 'submit', 'update:title']);

// 编辑器实例 shallowRef
const editorRef = shallowRef();

// 内容 HTML
const valueHtml = ref<string>('');
watch(
  () => props.value,
  nval => {
    valueHtml.value = nval ? `${nval}` : '';
  },
  { immediate: true }
);

const title = ref(props.title ?? '');
watch(
  () => props.title,
  nval => {
    title.value = nval || '';
  },
  { immediate: true }
);

// 工具栏配置
// const customSave = {
//   key: 'saveBtn',
//   factory() {
//     return new CustomBtn({ title: '保存', eventKey: 'saveSubmit' });
//   },
// };
// Boot.registerMenu(customSave);
const toolbarConfig: Partial<IToolbarConfig> = {
  excludeKeys: ['group-video', 'codeBlock', 'emotion', 'fullScreen'],
};

// 编辑器的配置
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  ...(props.editConfig ?? {}),
  MENU_CONF: {
    uploadImage: {
      async customUpload(file: File, insertFn: InsertFnType) {
        const res = await customRequest(file);

        // url 必须，图片显示地址，其他非必须 url, alt, href
        insertFn(formatImgUrl(res.data.data.filepath ?? ''));
      },
    },
    saveBtn: {
      getValue: e => {
        console.log('🚀 ~ e:', e);
      },
      // getValue()
    },
  },
};

// 编辑器创建完毕时的回调函数。
const handleCreated = (editor: DomEditor) => {
  editorRef.value = editor;
  const toolbar = editor.getConfig();
  editor.on('saveSubmit', () => {
    emits(
      'submit',
      props.valueType == 'html' ? editor.getHtml() : editor.getText()
    );
  });
};

const handlerChange = e => {
  let text = e.getText();
  if (text) {
    emits(
      'update:value',
      props.valueType == 'html' ? e.getHtml() : e.getText()
    );
  }
};

const inputChange = () => {
  emits('update:title', title);
};

// 自定义上传
const customRequest = async file => {
  let form = new FormData();
  form.append('storagetype', 'LOCAL');
  form.append('file', file);
  form.append('bucket', nullC(props.fileParams['bucket']));
  form.append('biztype', nullC(props.fileParams['biztype']));
  return await fileApi.upload(form);
};

onMounted(() => {});

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  initValue = '';
  if (editor == null) return;
  editor.destroy();
});
</script>

<style lang="scss" scoped>
.u-editor-tool {
  display: flex;
  justify-content: center;
  border-bottom: 1px solid #e8e8e8;
  // border-top: 1px solid #e8e8e8;
}
.u-editor {
  width: 100%;
  min-width: 600px;
  min-height: 300px;
  margin: auto;
  background-color: #fff;
  padding: 20px 50px 20px;
  border: 1px solid #e8e8e8;
  box-shadow: 0 2px 10px rgb(0 0 0 / 12%);
  overflow: auto;
  box-sizing: border-box;
}
:deep(button[data-menu-key='saveBtn']) {
  background-color: #1890ff !important;
  color: #fff;
  width: 55px !important;
}

.u-tencent-editor {
  .u-tencent-editor-box {
    height: calc(100% - 100px);
    // background-color: rgb(245, 245, 245);
    // overflow-y: auto;
    position: relative;
  }

  .editor-container {
    width: 65%;
    min-width: 850px;
    min-height: 300px;
    margin: 20px auto 40px auto;
    background-color: #fff;
    padding: 20px 50px 50px 50px;
    border: 1px solid #e8e8e8;
    box-shadow: 0 2px 10px rgb(0 0 0 / 12%);
  }

  .u-editor {
    box-shadow: unset !important;
    min-height: 450px !important;
  }

  #title-container {
    padding: 20px 0;
    border-bottom: 1px solid #e8e8e8;
  }

  #title-container input {
    font-size: 30px;
    border: 0;
    outline: none;
    width: 100%;
    line-height: 1;
  }
}
</style>
